package mn.idax.exchange.otc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import mn.idax.exchange.common.CalendarUtil;
import mn.idax.exchange.otc.domain.*;
import mn.idax.exchange.otc.entity.Country;
import mn.idax.exchange.otc.entity.*;
import mn.idax.exchange.otc.enums.AdEnum;
import mn.idax.exchange.otc.enums.response.OTCAdResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.mapper.*;
import mn.idax.exchange.otc.service.*;
import mn.idax.exchange.otc.util.*;
import mn.idax.exchange.otc.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: shihaiming
 * @Date: 2018/7/30 16:41
 * @Description:
 */
@Service
@SuppressWarnings("all")
public class OTCAdsServiceImpl implements OTCAdsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OTCAdsServiceImpl.class);

    @Autowired
    private OTCAdsMapper otcAdsMapper;
    @Autowired
    private OTCAdWayMapper otcAdWayMapper;
    @Autowired
    private OTCUserGroupMapper otcUserGroupMapper;
    @Autowired
    private OTCBusinessApplyMapper OTCBusinessApplyMapper;
    @Autowired
    private OTCPayModeDetailMapper otcPayModeDetailMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private FileUrlService fileUrlService;

    @Autowired
    private CountryService countryService;

    @Autowired
    private OTCAdWayService otcAdWayService;

    @Autowired
    private OTCPayModeDetailService otcPayModeDetailService;

    @Autowired
    private OTCOrderService otcOrderService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addOTCAds(OTCAds record, List<OTCAdWay> otcAdWayList) throws IdaxException {
        //添加广告信息
        int count = otcAdsMapper.insertSelective(record);
        if (count == 0) {
            LogUtils.warn(this.getClass(), "addOTCAdsFail,record: " + JSON.toJSONString(record));
            throw new IdaxException(OTCAdResponseEnum.INSERT_FAIL.getCode());
        }
        for (int i = 0; i < otcAdWayList.size(); i++) {
            //添加广告交易方式
            otcAdWayList.get(i).setAdid(record.getId());
            count = otcAdWayMapper.insertSelective(otcAdWayList.get(i));
            if (count == 0) {
                LogUtils.warn(this.getClass(), "addOTCAdWayListFail,otcAdWayList: " + otcAdWayList.get(i));
                throw new IdaxException(OTCAdResponseEnum.INSERT_FAIL.getCode());
            }
        }
    }

    @Override
    public boolean verifyPublishAdvertising(Integer userId, Integer coinId, Integer type) {
        OTCAdsExample adsExample = new OTCAdsExample();
        adsExample.createCriteria()
                .andPublisheridEqualTo(userId)
                .andTypeEqualTo(type)
                .andStateEqualTo(AdEnum.state_up.getCode())
                .andPairidEqualTo(coinId);

        List<OTCAds> listAd = this.otcAdsMapper.selectByExample(adsExample);

        return listAd.size() >= 1;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateOTCAds(OTCAds record, List<OTCAdWay> otcAdWayList) {
        //修改广告时,将原有的交易方式逻辑删除，重新插入新提交的
        OTCAdWay otcAdWay = new OTCAdWay();
        otcAdWay.setAdid(record.getId());
        otcAdWay.setUpdatetime(DateUtils.getUTCNow());
        int count = otcAdWayMapper.logicDelByAdId(otcAdWay);
        if (count == 0) {
            throw new IdaxException(OTCAdResponseEnum.UPDATE_FAIL.getCode());
        }
        for (OTCAdWay adWay : otcAdWayList) {
            //添加广告交易方式
            count = otcAdWayMapper.insertSelective(adWay);
            if (count == 0) {
                LogUtils.warn(this.getClass(), "adWayInsertFail,adWay: " + JSON.toJSONString(adWay));
                throw new IdaxException(OTCAdResponseEnum.INSERT_FAIL.getCode());
            }
        }
        count = otcAdsMapper.updateOTCAds(record);
        if (count != 1) {
            throw new IdaxException(OTCAdResponseEnum.UPDATE_FAIL.getCode());
        }
        return count;
    }

    @Override
    public OTCAds selectByPrimaryKey(Integer id) {
        return otcAdsMapper.selectByPrimaryKey(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateOTCAdsStateById(OTCAds record) {
        return otcAdsMapper.updateOTCAdsStateById(record);
    }

    @Override
    public int expireBatchOTCAdsState(Map<String, Object> map) {
        return otcAdsMapper.expireBatchOTCAdsState(map);
    }

    @Override
    public int insertSelective(OTCAds record) {
        return otcAdsMapper.insertSelective(record);
    }

    @Override
    public AccountDTO selectAvailableAmountByUserIdAndCoinId(AccountDTO accountDTO) {
        return otcAdsMapper.selectAvailableAmountByUserIdAndCoinId(accountDTO);
    }

    @Override
    public ADShowResultDTO getADPage(OTCAdPageDTO otcAdPageDTO) {
        //查询list
        List<ADPageListDTO> adList = otcAdsMapper.getADList(otcAdPageDTO);

        if (adList.isEmpty()) {
            return new ADShowResultDTO(new ArrayList<>(), 0);
        }
        //查询total
        Integer total = otcAdsMapper.getADTotal(otcAdPageDTO);
        for (ADPageListDTO adPageListDTO : adList) {
            //查询广告支持的交易方式
            adPageListDTO.setNickName(NickNameUtils.concatNickName(adPageListDTO.getNickName(), adPageListDTO.getEmial()));
            adPageListDTO.setEmial(null);
            List<Integer> wayList = otcAdWayMapper.selectDisplayTradeTypeByAdId(adPageListDTO.getId());
            adPageListDTO.setTransactionWayList(wayList);

            //查询信任数
            int trustNumber = 0;
            trustNumber = otcUserGroupMapper.countTrustGroupTotalByUserId(adPageListDTO.getPublisherid());
            adPageListDTO.setTrustNumber(trustNumber);

            //返回前端后，置空发布人用户id
            adPageListDTO.setPublisherid(null);
        }
        return new ADShowResultDTO(adList, total);
    }

    @Override
    public ADShowResultDTO getMyADList(OTCMyAdPageDTO otcMyAdPageDTO) throws Exception {
        //查询list
        List<ADPageListDTO> adList = otcAdsMapper.getMyADList(otcMyAdPageDTO);

        if (adList.isEmpty()) {
            return new ADShowResultDTO(new ArrayList<>(), 0);
        }
        //查询total
        Integer total = otcAdsMapper.getMyADTotal(otcMyAdPageDTO);

        //查询广告支持的交易方式 todo 一起查出来
        for (ADPageListDTO adPageListDTO : adList) {
            List<Integer> wayList = otcAdWayMapper.selectDisplayTradeTypeByAdId(adPageListDTO.getId());
            adPageListDTO.getTransactionWayList().addAll(wayList);
        }

        return new ADShowResultDTO(dealADListResult(adList), total);
    }

    List<ADPageListDTO> dealADListResult(List<ADPageListDTO> adList) throws Exception {
        List<ADPageListDTO> list = new ArrayList<>();
        for (ADPageListDTO adPageListDTO : adList) {
            ADPageListDTO result = new ADPageListDTO();
            BeanUtils.copyProperties(adPageListDTO,result);
            result.setIsFloating(adPageListDTO.getIsFloating());
            result.setPrice(adPageListDTO.getIsFloating() ? this.floatingAdsPriceConvert(
                    new FloatingPriceDTO(adPageListDTO.getType(),adPageListDTO.getMinprice(),adPageListDTO.getMaxprice(),
                            adPageListDTO.getUnit(),adPageListDTO.getExchange(),adPageListDTO.getPairname(),adPageListDTO.getPrice(),adPageListDTO.getFloatingrate())
            ).getPrice(): adPageListDTO.getPrice());
            result.setFloatingrate(null);
            result.setMinprice(null);
            result.setMaxprice(null);
            result.setExchange(null);
            result.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(result.getTransactionWayList()));
//            result.setIconUrl(fileUrlService.dealFileUrlAddress(result.getIconUrl()));
            result.setExpireTimeAddT(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adPageListDTO.getExpireTime()));
            result.setNumber(adPageListDTO.getNumber());
            list.add(result);
        }
        return list;
    }

    @Override
    public int updateTradenumberToOTCAds(OTCAds criteriaAds, Integer oldTradenumber) {
        OTCAdsExample otcAdsExample = new OTCAdsExample();
        otcAdsExample.createCriteria()
                .andIdEqualTo(criteriaAds.getId())
                .andTradenumberEqualTo(oldTradenumber);

        OTCAds updateAds = new OTCAds();
        updateAds.setTradenumber(oldTradenumber + 1);
        updateAds.setUpdatetime(DateUtils.getCalendarToDate(CalendarUtil.getUTCDate(new Date())));

        return this.otcAdsMapper.updateByExampleSelective(updateAds, otcAdsExample);
    }

    @Override
    public BigDecimal getMaxPrice(String pairname) {
        return otcAdsMapper.getMaxPrice(pairname);
    }

    @Override
    public BigDecimal getMinPrice(String pairname) {
        return otcAdsMapper.getMinPrice(pairname);
    }

    @Override
    public List<OTCAds> getAvailableAmountLessThanLimtList(OTCAutoDownAdDTO otcAutoDownAdDTO) {
        return otcAdsMapper.getAvailableAmountLessThanLimtList(otcAutoDownAdDTO);
    }

    @Override
    public int updateStateOTCAdsById(OTCAutoDownAdDTO otcAutoDownAdDTO) {
        return otcAdsMapper.updateStateOTCAdsById(otcAutoDownAdDTO);
    }

    @Override
    public List<OTCAds> getExpireBatchOTCAdsState(Map<String, Object> map) {
        return otcAdsMapper.getExpireBatchOTCAdsState(map);
    }

    @Override
    public ADShowResultDTO getOtherUserADList(OTCAdvertiserDTO otcAdvertiserDTO) throws Exception {


//        if (adList.isEmpty()) {
//            return new ADShowResultDTO(new ArrayList<>(), 0);
//        }
        //查询total
        Integer total = otcAdsMapper.getOtherUserADTotal(otcAdvertiserDTO);
        if (total.equals(0)){
            return new ADShowResultDTO(new ArrayList<>(), 0);
        }

        //查询list
        List<ADPageListDTO> adList = otcAdsMapper.getOtherUserADList(otcAdvertiserDTO);

        //查询广告支持的交易方式
        for (int i = 0; i < adList.size(); i++) {
            List<Integer> wayList = otcAdWayMapper.selectDisplayTradeTypeByAdId(adList.get(i).getId());
            adList.get(i).getTransactionWayList().addAll(wayList);
        }

        return new ADShowResultDTO(dealADListResult(adList), total);
    }

    //获取信用最高的广告单和最具性价比的广告单
    @Override
    public List<ADRecommendListResult> getRecommendAds(RecommendAdsRequest request) throws Exception {

        List<ADRecommendListDTO> quaryList = new ArrayList<>();

        //最具性价比的广告 买时推荐价格最低 卖时推荐价格最高
        if (request.getType().intValue() == AdEnum.type_buy.getCode()) {
            List<ADRecommendListDTO> buyAavailableAd = otcAdsMapper.getBuyAvailableAd(request);
            if (!buyAavailableAd.isEmpty()) {
                List<ADRecommendListDTO> list = getFloatingPrice(buyAavailableAd);
                //按价格递减  a.Price DESC,
                list.sort((o1, o2) -> o2.getPrice().compareTo(o1.getPrice()));
                quaryList.add(list.get(0));
            }
        } else {
            List<ADRecommendListDTO> sellAavailableAd = otcAdsMapper.getSellAvailableAd(request);
            if (!sellAavailableAd.isEmpty()) {
                List<ADRecommendListDTO> list = getFloatingPrice(sellAavailableAd);
                //按价格递增  a.Price ASC,
                list.sort((o1, o2) -> o1.getPrice().compareTo(o2.getPrice()));
                quaryList.add(list.get(0));
            }
        }

        //查询信誉最高的广告
        ADRecommendListDTO recAd = otcAdsMapper.getPraiseRecommendAd(request);
        if (recAd != null) {
            quaryList.add(recAd);
        }

        return dealgetRecommendAds(quaryList);

    }

    private List<ADRecommendListResult> dealgetRecommendAds(List<ADRecommendListDTO> adPageListDTOS) throws Exception {
        List<ADRecommendListResult> RecList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(adPageListDTOS)) {
            for (ADRecommendListDTO adPageListDTO : adPageListDTOS) {
                ADRecommendListResult result = new ADRecommendListResult();
                BeanUtils.copyProperties(adPageListDTO, result);
                result.setIsFloating(adPageListDTO.getIsFloating());
                result.setPrice(adPageListDTO.getIsFloating() ? this.floatingAdsPriceConvert(
                        new FloatingPriceDTO(adPageListDTO.getType(),adPageListDTO.getMinprice(),adPageListDTO.getMaxprice(),
                                adPageListDTO.getUnit(),adPageListDTO.getExchange(),adPageListDTO.getPairname(),adPageListDTO.getPrice(),adPageListDTO.getFloatingrate())
                ).getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString() : adPageListDTO.getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString());
                result.setNickName(NickNameUtils.concatNickName(adPageListDTO.getNickName(), adPageListDTO.getEmial()));
                result.setCreateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adPageListDTO.getCreateTime()));
                result.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adPageListDTO.getUpdateTime()));
                result.setEmial(null);
                result.setPublisherid(null);
                result.setIconUrl(fileUrlService.dealFileUrlAddress(result.getIconUrl()));
                result.setIsBusinesser(adPageListDTO.getIsBusinesser() == 0 ? false : true);
                result.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(result.getTransactionWayList()));
                result.setUserId(adPageListDTO.getUserId());
                if (Objects.isNull(MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adPageListDTO.getPublisherid()))){
                    result.setProportion(BigDecimal.ZERO);
                    result.setTradeTotal(0);
                    result.setTradeRate(BigDecimal.ZERO);
                } else {
                    ProportionDTO proportionDTO = MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adPageListDTO.getPublisherid());
                    result.setProportion(proportionDTO.getProportion());
                    result.setTradeTotal(proportionDTO.getTradeTotal());
                    result.setTradeRate(proportionDTO.getTradeRate());
                }
                result.setNumber(adPageListDTO.getNumber()==null?"0":adPageListDTO.getNumber().setScale(6,BigDecimal.ROUND_DOWN).toPlainString());
                RecList.add(result);
            }
            return RecList;
        }
        return RecList;
    }

    /**
     * 推荐的广告替换价格
     * @param adPageListDTOS
     * @return
     * @throws Exception
     */
    private List<ADRecommendListDTO> getFloatingPrice(List<ADRecommendListDTO> adPageListDTOS) throws Exception {
        List<ADRecommendListDTO> RecList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(adPageListDTOS)) {
            for (ADRecommendListDTO adPageListDTO : adPageListDTOS) {
                ADRecommendListDTO result = new ADRecommendListDTO();
                BeanUtils.copyProperties(adPageListDTO,result);
                if (adPageListDTO.getIsFloating()){
                    result.setPrice(this.floatingAdsPriceConvert(
                            new FloatingPriceDTO(adPageListDTO.getType(), adPageListDTO.getMinprice(), adPageListDTO.getMaxprice(),
                                    adPageListDTO.getUnit(), adPageListDTO.getExchange(), adPageListDTO.getPairname(), adPageListDTO.getPrice(), adPageListDTO.getFloatingrate())
                    ).getPrice().setScale(2, BigDecimal.ROUND_DOWN));
                }
                RecList.add(result);
            }
        }
        return RecList;
    }


    /**
     * v2广告 查询 list
     *
     * @param otcAdPageDTO
     * @return
     */
    @Override
    public List<ADRecommendListResult> getADPageSec(OTCAdPageSecDTO otcAdPageDTO) throws Exception {
        List<ADRecommendListDTO> adList = otcAdsMapper.getADPageSec(otcAdPageDTO);

        return dealgetRecommendAds(adList);
    }

    @Override
    public Integer getADPageTotalSec(OTCAdPageSecDTO otcAdPageDTO) {

        return otcAdsMapper.getADPageTotalSec(otcAdPageDTO);
    }

    @Override
    public List<OTCAds> getMarketMaxPrice(AdMarketPrice adMarketPrice) {

        return otcAdsMapper.getMarketMaxPrice(adMarketPrice);
    }

    @Override
    public List<OTCAds> getMarketMinPrice(AdMarketPrice adMarketPrice) {
        return otcAdsMapper.getMarketMinPrice(adMarketPrice);
    }

    //用户输入的国家和法币是否和支付方式对应
    @Override
    public Boolean payTypeIsMatch(Integer country, String unit, Integer[] trademode) {

        OTCPayModeDetailExample example = new OTCPayModeDetailExample();
        example.createCriteria().andIsenableEqualTo(true)
                .andCountryidEqualTo(country)
                .andCurrencyEqualTo(unit);
        List<OTCPayModeDetail> otcPayModeDetails = otcPayModeDetailMapper.selectByExample(example);
        if (otcPayModeDetails.isEmpty()) {
            return false;
        }
        //获取数据库支持的支付方式 todo 高效
        String paymethod = otcPayModeDetails.get(0).getPaymethod();
        Integer[] dbPayType = new Integer[10];
        String[] split = paymethod.split(",");
        for (int i = 0; i < split.length; i++) {
            dbPayType[i] = Integer.valueOf(split[i]);
        }

        return Arrays.asList(dbPayType).containsAll(Arrays.asList(trademode));
    }

    @Override
    public FloatingPriceDTO floatingAdsPriceConvert(FloatingPriceDTO floatingPrice) throws Exception {
        // 获取当前价格
        BigDecimal floatingAdPrice = BigDecimal.ZERO,nowPrice = null;
        // 价格替换
        List<ExchageMarketPrice> exchageMarketPrices = JSONArray.parseArray(MemoryService.SYSTEMSETTINGMAP.get((floatingPrice.getPairname()+floatingPrice.getUnit()).toUpperCase()).toString(), ExchageMarketPrice.class);
        for (ExchageMarketPrice exchageMarketPrice : exchageMarketPrices) {
            if(exchageMarketPrice.getExchange().equals(floatingPrice.getExchange())){
                nowPrice = exchageMarketPrice.getPrice();
            }
        }
        // 如果没有最新价则 根据买卖方向 返回最小最大价格
        /**
         * 最新价格是否在浮动价之间 在 ？ 直接返回 ： 分买卖类型给最低价或者最高价
         */
        if (null == nowPrice) {
            floatingAdPrice = floatingPrice.getType().equals(AdEnum.type_buy.getCode()) ? floatingPrice.getMinprice() : floatingPrice.getMaxprice();
            LOGGER.warn("RAMPrice data is empty");
        }else{
            // 计算浮动率
            floatingAdPrice = PercentageUtils.calculation(nowPrice, floatingPrice.getFloatingrate());
        }
        floatingPrice.setPrice(floatingAdPrice);
        return floatingPrice;
    }

    @Override
    public List<FrozenUserAdDTO> getFrozenUserPublishAds() {

        return otcAdsMapper.getFrozenUserPublishAds();
    }

    @Override
    public MyAdDetailDTO getMyAdDetail(OTCAds otcAds, Integer userId, HttpServletRequest request) throws Exception {

        MyAdDetailDTO myAdDetailDTO = new MyAdDetailDTO();
        BeanUtils.copyProperties(otcAds,myAdDetailDTO);

        myAdDetailDTO.setPublishtime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(otcAds.getCreatetime()));
        myAdDetailDTO.setExpiretime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(otcAds.getExpiretime()));

        //替换价格
        if (otcAds.getIsfloating()){
            FloatingPriceDTO floatingPriceDTO = floatingAdsPriceConvert(new FloatingPriceDTO(otcAds.getType(), otcAds.getMinprice(), otcAds.getMaxprice(),
                    otcAds.getUnit(), otcAds.getExchange(), otcAds.getPairname(), otcAds.getPrice(), otcAds.getFloatingrate()));

            myAdDetailDTO.setPrice(floatingPriceDTO.getPrice());
        } else {
            myAdDetailDTO.setPrice(otcAds.getPrice());
        }

        Country country = countryService.getCountryById(otcAds.getCountry());
        String language = ParamUtils.getLanguageByRequest(request);
        if (language.substring(0,2).equalsIgnoreCase("zh")){
            myAdDetailDTO.setCountryName(country.getNamecn());
            myAdDetailDTO.setTypeNational(otcAds.getType().equals(AdEnum.type_buy.getCode()) ? "购买" : "出售");
            myAdDetailDTO.setPayTiemLimit("15分钟");
        } else {
            myAdDetailDTO.setCountryName(country.getNameen());
            myAdDetailDTO.setTypeNational(otcAds.getType().equals(AdEnum.type_buy.getCode()) ? "buy" : "sell");
            myAdDetailDTO.setPayTiemLimit("15 minutes");
        }

        //查询支付方式
        List<Integer> tradeType = otcAdWayService.selectDisplayTradeTypeByAdId(otcAds.getId());
        myAdDetailDTO.setPayType(tradeType);
        myAdDetailDTO.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(tradeType));

        //支持的所有国家-法币-支付方式
        List<OTCPayModeDetail> enablePayModeDetail = otcPayModeDetailService.getEnablePayModeDetail();

        List<OTCPayModeDetail> collect = enablePayModeDetail.stream().filter(p -> otcAds.getCountry().equals(p.getCountryid()))
                .collect(Collectors.toList());

        //国家和支付方式作了同步 即使法币不同 支付方式不受影响 如果后续改规则 这里要改
        String paymethod = collect.get(0).getPaymethod();
        List<String> payTypeNation = OTCPayTypeNationUtils.getPayType(paymethod);
        myAdDetailDTO.setCountryPayTypeNation(payTypeNation);
        myAdDetailDTO.setCountryPayType(paymethod.split(","));
        myAdDetailDTO.setNumber(otcAds.getNumber()==null?"0":otcAds.getNumber().toPlainString());

        return myAdDetailDTO;
    }

    @Override
    public List<Integer> getAllUpAdPublisherId() {
        return otcAdsMapper.getAllUpAdPublisherId();
    }

    @Override
    public Integer getCountOfUserUpAd(Integer userId) {
        return otcAdsMapper.getCountOfUserUpAd(userId);
    }

    @Override
    public void getUserProportion() {
        List<Integer> allUpAdPublisherId = getAllUpAdPublisherId();
        LogUtils.info(this.getClass(),"getAllUpAdPublisherId data" +  JSON.toJSONString(allUpAdPublisherId));
        if (!allUpAdPublisherId.isEmpty()){
            List<UserTradeInfo> userTradeInfos = otcOrderService.getUserTwoMonthsAgoTradeInfo(allUpAdPublisherId);
            LogUtils.info(this.getClass(),"userTradeInfos data" +  JSON.toJSONString(userTradeInfos));
            otcOrderService.calculationUserProportion(userTradeInfos,allUpAdPublisherId);
        }

    }

    /**
     * 将广告从内存中移除
     * @param adId
     */
    @Override
    public void removeAdFromMemory(Integer adId,Integer publisherId){
        List<ADRecommendListResult> adList = MemoryService.AD_LIST.get("adList");
        LOGGER.info("removeAdFromMemory :" + adId);
        adList.removeIf(p ->p.getId().equals(adId));
        //adList 没有Publisherid 只能查数据库
        if (getCountOfUserUpAd(publisherId) < 2){
            MemoryService.AD_PUBLISER_PROPORTION_MAP.remove(publisherId);
        }
    }


    /**
     * 将广告添加进内存
     * @param adId
     * @throws Exception
     */
    @Override
    public void addAdInMemory(Integer adId) throws Exception {
        ADRecommendListDTO adDetailInfo = getAdDetailInfo(adId);

        ADRecommendListResult result = new ADRecommendListResult();
        BeanUtils.copyProperties(adDetailInfo, result);
        result.setIsFloating(adDetailInfo.getIsFloating());
        result.setPrice(adDetailInfo.getIsFloating() ? floatingAdsPriceConvert(
                new FloatingPriceDTO(adDetailInfo.getType(),adDetailInfo.getMinprice(),adDetailInfo.getMaxprice(),
                        adDetailInfo.getUnit(),adDetailInfo.getExchange(),adDetailInfo.getPairname(),adDetailInfo.getPrice(),adDetailInfo.getFloatingrate())
        ).getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString() : adDetailInfo.getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString());
        result.setNickName(NickNameUtils.concatNickName(adDetailInfo.getNickName(), adDetailInfo.getEmial()));
        result.setCreateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adDetailInfo.getCreateTime()));
        result.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adDetailInfo.getUpdateTime()));
        result.setIsBusinesser(adDetailInfo.getIsBusinesser() == 0 ? false : true);
        result.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(result.getTransactionWayList()));

        if (Objects.isNull(MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adDetailInfo.getPublisherid()))) {
            List<Integer> list = Lists.newArrayList();
            list.add(adDetailInfo.getPublisherid());
            List<UserTradeInfo> userTradeInfos = otcOrderService.getUserTwoMonthsAgoTradeInfo(list);
            otcOrderService.calculationUserProportion(userTradeInfos, list);
        }
        ProportionDTO proportionDTO = MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adDetailInfo.getPublisherid());
        result.setProportion(proportionDTO.getProportion());
        result.setTradeTotal(proportionDTO.getTradeTotal());
        result.setTradeRate(proportionDTO.getTradeRate());
        result.setEmial(null);
        result.setPublisherid(null);
        MemoryService.AD_LIST.get("adList").add(result);
    }

    /**
     * 查询单个广告信息--上架 发布时加内存时用
     */
    @Override
    public ADRecommendListDTO getAdDetailInfo(Integer adId){

        return otcAdsMapper.getAdDetailInfo(adId);
    }

    /**
     * 线上两台 用了topic，上架同
     * @param msg
     */
    @JmsListener(destination = "OTC_AD_DOWN_TOPIC")
    public void removeAdFromMemoryByAmq(String msg) {

        SyncAdInMemory syncAdInMemory = JSON.parseObject(msg, SyncAdInMemory.class);
        LogUtils.info(this.getClass(),"removeAdFromMemoryByAmq adid: " + syncAdInMemory.getAdId());
        List<ADRecommendListResult> adList = MemoryService.AD_LIST.get("adList");
        adList.removeIf(p ->p.getId().equals(syncAdInMemory.getAdId()));
        if (!CollectionUtils.isEmpty(adList)) {
            //adList 没有Publisherid 只能查数据库
            if (getCountOfUserUpAd(syncAdInMemory.getPublisherId()) < 2){
                MemoryService.AD_PUBLISER_PROPORTION_MAP.remove(syncAdInMemory.getPublisherId());
            }
        }
    }

    @JmsListener(destination = "OTC_AD_UP_TOPIC")
    public void addAdFromMemoryByAmq(String msg) throws Exception {
        SyncAdInMemory syncAdInMemory = JSON.parseObject(msg, SyncAdInMemory.class);
        LogUtils.info(this.getClass(),"addAdFromMemoryByAmq adid: " + syncAdInMemory.getAdId());
        ADRecommendListDTO adDetailInfo = getAdDetailInfo(syncAdInMemory.getAdId());

        ADRecommendListResult result = new ADRecommendListResult();
        BeanUtils.copyProperties(adDetailInfo, result);
        result.setIsFloating(adDetailInfo.getIsFloating());
        result.setPrice(adDetailInfo.getIsFloating() ? floatingAdsPriceConvert(
                new FloatingPriceDTO(adDetailInfo.getType(),adDetailInfo.getMinprice(),adDetailInfo.getMaxprice(),
                        adDetailInfo.getUnit(),adDetailInfo.getExchange(),adDetailInfo.getPairname(),adDetailInfo.getPrice(),adDetailInfo.getFloatingrate())
        ).getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString() : adDetailInfo.getPrice().setScale(2,BigDecimal.ROUND_DOWN).toPlainString());
        result.setNickName(NickNameUtils.concatNickName(adDetailInfo.getNickName(), adDetailInfo.getEmial()));
        result.setCreateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adDetailInfo.getCreateTime()));
        result.setUpdateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(adDetailInfo.getUpdateTime()));
        result.setIsBusinesser(adDetailInfo.getIsBusinesser() == 0 ? false : true);
        result.setPayTypeIcon(OTCPayTypeNationUtils.getPayTypeIcon(result.getTransactionWayList()));

        if (Objects.isNull(MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adDetailInfo.getPublisherid()))) {
            List<Integer> list = Lists.newArrayList();
            list.add(adDetailInfo.getPublisherid());
            List<UserTradeInfo> userTradeInfos = otcOrderService.getUserTwoMonthsAgoTradeInfo(list);
            otcOrderService.calculationUserProportion(userTradeInfos, list);
        }
        ProportionDTO proportionDTO = MemoryService.AD_PUBLISER_PROPORTION_MAP.get(adDetailInfo.getPublisherid());
        result.setProportion(proportionDTO.getProportion());
        result.setTradeTotal(proportionDTO.getTradeTotal());
        result.setTradeRate(proportionDTO.getTradeRate());
        result.setEmial(null);
        result.setPublisherid(null);
        MemoryService.AD_LIST.get("adList").add(result);
    }

}
